use lettre::{Address, Message, Transport};
use lettre::message::{header, IntoBody, Mailbox};
use lettre::transport::smtp::authentication::Credentials;
use lettre::transport::smtp::Error;
use lettre::transport::smtp::response::Response;
use crate::工具包::email::{EmailBody, EmailBuilder, EmailMessage, EmailSend,};
use crate::工具包::get_self_config;


pub struct QqEmail<S:Into<String>,T: IntoBody>{
	from_name: Option<String>,
	to:Vec<Mailbox>,
	cc:Vec<Mailbox>,
	bcc:Vec<Mailbox>,
	subject:Option<S>,
	body:EmailBody<T>,
}

impl<S:Into<String>,T: IntoBody> Default for QqEmail<S,T> {
	fn default() -> Self {
		QqEmail{
			from_name:None,
			to: vec![],
			cc: vec![],
			bcc: vec![],
			subject: None,
			body: EmailBody::Null
		}
	}
}

impl<S:Into<String>,T: IntoBody> QqEmail<S, T> {
	pub fn new() -> QqEmail<S, T>{
		QqEmail{
			..Default::default()
		}
	}
}

impl<S:Into<String>,T: IntoBody> EmailMessage for QqEmail<S, T> {
	
	fn get_credentials() -> Credentials {
		let config = &get_self_config().qq_email;
		Credentials::new(config.account.clone()
		                 ,config.authorization_code.clone())
	}
	
	fn get_smtp_servers() -> &'static str {
		"smtp.qq.com"
	}
	
	fn get_mailbox(s: Option<String>) -> Mailbox {
		let add = Address::new(
			get_self_config().qq_email.account.clone()
			,"qq.com").unwrap();//电子邮件地址解析错误...,应该不会错
		if let Node = &s {//使用默认名
			let config = &get_self_config().qq_email.name;
			if let Some(v) = config {
				return Mailbox::new( Some(v.clone())  , add);
			}
			return Mailbox::new( None , add);//没有默认名
		}
		Mailbox::new(s,add)
	}
}

impl<S:Into<String>,T: IntoBody> EmailBuilder<S,T> for QqEmail<S, T> {
	fn from_name(mut self, s: String) -> Self {
		self.from_name = Some(s);
		self
	}
	
	fn to(mut self, mut to: Vec<Mailbox>) -> Self {
		self.to.append(&mut to);
		self
	}
	
	fn cc(mut self, mut cc: Vec<Mailbox>) -> Self {
		self.cc.append(&mut cc);
		self
	}
	
	fn bcc(mut self, mut bcc: Vec<Mailbox>) -> Self {
		self.bcc.append(&mut bcc);
		self
	}
	
	fn subject(mut self, subject: S) -> Self {
		self.subject = Some(subject);
		self
	}
	
	fn body(mut self, body: EmailBody<T>) -> Self {
		self.body = body;
		self
	}
}

impl<S:Into<String>,T: IntoBody> EmailSend for QqEmail<S,T> {
	fn send(self) -> Result<Response,Error> {
		let mut email = Message::builder();
		email = email.from(Self::get_mailbox(self.from_name));
		email = match self.subject {
			Some(v) => email.subject(v),
			None => email.subject("")
		};
		for v in self.to {
			email = email.to(v);
		}
		for v in self.cc {
			email = email.cc(v);
		}
		for v in self.bcc {
			email = email.bcc(v);
		}
		let email = match self.body {
			EmailBody::Text(v) => {
				email = email.header(header::ContentType::TEXT_PLAIN);
				email.body(v)
			}
			EmailBody::Html(v) => {
				email = email.header(header::ContentType::TEXT_HTML);
				email.body(v)
			}
			EmailBody::Null => email.body(String::new())
		};
		let email = email.expect("[Err]:邮件格式不应该失败");  // 邮件内容
		
		Self::get_smtp_transport().send(&email)
	}
}